package org.thoughtworks.selenium.flex.ui;

import org.thoughtworks.selenium.flex.codec.KeyModifier;
import org.thoughtworks.selenium.flex.driver.Command;
import org.thoughtworks.selenium.flex.driver.FlexDriver;
import org.thoughtworks.selenium.flex.driver.SeleniumFlexDriver;

import java.lang.reflect.Constructor;

public class DisplayObject {

    private DisplayObject parent;
    protected String currentLocator;
    protected FlexDriver driver;

    protected DisplayObject(DisplayObject parent, AutomationIdMap locator, FlexDriver driver) {
        this.parent = parent;
        this.currentLocator = locator.toString();
        this.driver = driver;
    }

    protected DisplayObject(DisplayObject parent, String locator, FlexDriver driver) {
        this.parent = parent;
        this.currentLocator = locator;
        this.driver = driver;
    }

    public <T> T Flex(Class<T> clazz, String idOrName) throws Exception {
        String resolvedLocator = ((SeleniumFlexDriver) driver).executeSeleniumAccessorCommand("getElementsByFlexId", new String[]{idOrName,});
        Constructor<T> constructor = clazz.getDeclaredConstructor(DisplayObject.class, String.class, FlexDriver.class);
        constructor.setAccessible(true);
        return constructor.newInstance(null, resolvedLocator, driver);
    }


    public <T> T Flex(Class<T> clazz, AutomationIdMap automationIdMap) throws Exception {
        Constructor<T> constructor = clazz.getDeclaredConstructor(DisplayObject.class, AutomationIdMap.class, FlexDriver.class);
        constructor.setAccessible(true);
        return constructor.newInstance(this, automationIdMap, driver);
    }

    public void MouseMove(int localX, int localY, KeyModifier keyModifier) {
        driver.execute(new Command("MouseMove", localX, localY, keyModifier), this);
    }

    public void Click(KeyModifier keyModifier) {
        driver.execute(new Command("Click", keyModifier), this);
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (parent != null)
            sb.append(parent.toString()).append("|");
        sb.append(currentLocator != null ? currentLocator : "");
        return sb.toString();
    }
}